package webapp.mvc.controllers;

import com.alibaba.fastjson.JSONObject;
import com.zoowii.formutils.BindingResult;
import com.zoowii.formutils.Validator;
import com.zoowii.jpa_utils.extension.Paginator;
import com.zoowii.jpa_utils.util.StringUtil;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import webapp.mvc.components.HttpManager;
import webapp.mvc.controllers.forms.CreateProductCommentForm;
import webapp.mvc.controllers.forms.CreateProductForm;
import webapp.mvc.controllers.forms.SimpleResponse;
import webapp.mvc.controllers.forms.UpdateProductForm;
import webapp.mvc.exceptions.ProductException;
import webapp.mvc.exceptions.UserException;
import webapp.mvc.models.CommentEntity;
import webapp.mvc.models.ProductChangeRequestEntity;
import webapp.mvc.models.ProductEntity;
import webapp.mvc.models.UserEntity;
import webapp.mvc.services.ICategoryService;
import webapp.mvc.services.IProductService;
import webapp.mvc.services.IShopService;
import webapp.mvc.services.IUserService;
import webapp.mvc.utils.HttpUtil;
import webapp.mvc.utils.NumberUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

@Controller
@RequestMapping("/product")
public class ProductController {
    private static final Logger LOG = LoggerFactory.getLogger(ProductController.class);
    @Autowired
    private Validator validator;
    @Autowired
    private IProductService productService;
    @Autowired
    private IShopService shopService;
    @Autowired
    private ICategoryService categoryService;
    @Autowired
    private IUserService userService;
    @Autowired
    private HttpManager httpManager;

    @RequestMapping("/list")
    public
    @ResponseBody
    String listProducts(HttpServletRequest request) {
        Paginator paginator = new Paginator();
        paginator.setPage(NumberUtils.tryParseInt(request.getParameter("page"), 1));
        paginator.setPageSize(NumberUtils.tryParseInt(request.getParameter("page_size"), 10));
//        paginator.setPageSize(10);
        paginator.getOrders().add(Pair.of("commentCount", false));
        paginator.getOrders().add(Pair.of("createTime", false));
        String shopId = request.getParameter("shop");
        List<ProductEntity> productEntities = productService.getProducts(shopId, paginator);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("records", productEntities);
        jsonObject.put("total", paginator.getTotal());
        return SimpleResponse.ok(jsonObject).toJSON();
    }

    @RequestMapping(value = "/search", method = {RequestMethod.GET, RequestMethod.POST})
    public
    @ResponseBody
    String searchProducts(HttpServletRequest request) {
        Paginator paginator = new Paginator();
        paginator.setPage(NumberUtils.tryParseInt(request.getParameter("page"), 1));
        paginator.setPageSize(NumberUtils.tryParseInt(request.getParameter("page_size"), 10));
//        paginator.setPageSize(10);
        paginator.getOrders().add(Pair.of("commentCount", false));
        paginator.getOrders().add(Pair.of("createTime", false));
        String keyword = request.getParameter("search");
        List<ProductEntity> productEntities = productService.searchProducts(keyword, paginator);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("records", productEntities);
        jsonObject.put("total", paginator.getTotal());
        return SimpleResponse.ok(jsonObject).toJSON();
    }

    @RequestMapping("/list_changes")
    public
    @ResponseBody
    String listProductChanges(HttpServletRequest request) {
        Paginator paginator = new Paginator();
        paginator.setPage(NumberUtils.tryParseInt(request.getParameter("page"), 1));
        paginator.setPageSize(NumberUtils.tryParseInt(request.getParameter("page_size"), 10));
        paginator.setPageSize(10);
        paginator.getOrders().add(Pair.of("createTime", false));
        List<ProductChangeRequestEntity> productChangeRequestEntities = productService.getProductChangeRequests(paginator);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("records", productChangeRequestEntities);
        jsonObject.put("total", paginator.getTotal());
        return SimpleResponse.ok(jsonObject).toJSON();
    }

    @RequestMapping(value = "/delete_comments", method = RequestMethod.POST)
    public
    @ResponseBody
    String deleteComments(HttpServletRequest request) {
        String idsStr = request.getParameter("ids");
        List<String> ids = Arrays.asList(idsStr.split(","));
        productService.deleteComments(ids);
        return SimpleResponse.ok(true).toJSON();
    }

    @RequestMapping(value = "/agree_product_change/{id}", method = RequestMethod.POST)
    public
    @ResponseBody
    String agreeProductChange(@PathVariable String id) {
        ProductEntity productEntity = productService.agreeProductChangeRequest(id);
        return SimpleResponse.ok(productEntity).toJSON();
    }

    @RequestMapping(value = "/disagree_product_change/{id}", method = RequestMethod.POST)
    public
    @ResponseBody
    String disagreeProductChange(@PathVariable String id) {
        ProductChangeRequestEntity productChangeRequestEntity = productService.disagreeProductChangeRequest(id);
        return SimpleResponse.ok(productChangeRequestEntity).toJSON();
    }

    @RequestMapping("/hotest")
    public
    @ResponseBody
    String getHotestProducts(HttpServletRequest request) {
        int limit = HttpUtil.getIntRequestParam(request, "limit", 5);
        List<ProductEntity> productEntities = productService.getHotestProducts(limit);
        return SimpleResponse.ok(productEntities).toJSON();
    }

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public @ResponseBody
    String createProduct(HttpServletRequest request, CreateProductForm createProductForm) {
        BindingResult bindingResult = validator.validate(createProductForm);
        if(bindingResult.hasErrors()) {
            return SimpleResponse.fail(bindingResult.getErrors().next().getErrorMessage()).toJSON();
        }
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        try {
            ProductEntity productEntity = productService.createProduct(userEntity.getId(), createProductForm);
            return SimpleResponse.ok(productEntity).toJSON();
        } catch (ProductException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
    }
    @RequestMapping(value = "/update/{productId}", method = RequestMethod.POST)
    public @ResponseBody
    String updateProduct(HttpServletRequest request, @PathVariable String productId, UpdateProductForm updateProductForm) {
        BindingResult bindingResult = validator.validate(updateProductForm);
        if(bindingResult.hasErrors()) {
            return SimpleResponse.fail(bindingResult.getErrors().next().getErrorMessage()).toJSON();
        }
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        try {
            ProductEntity productEntity = productService.updateProduct(userEntity.getId(), productId, updateProductForm);
            return SimpleResponse.ok(productEntity).toJSON();
        } catch (ProductException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
    }
    
    @RequestMapping("/info/{productId}")
    public @ResponseBody
    String getProduct(@PathVariable String productId) {
        ProductEntity productEntity = productService.findById(productId);
        if(productEntity == null) {
            return SimpleResponse.fail("找不到商品" + productId).toJSON();
        }
        return SimpleResponse.ok(productEntity).toJSON();
    }
    
    @RequestMapping("/comments/{productId}")
    public @ResponseBody
    String getProductComments(HttpServletRequest request, @PathVariable String productId) {
        Paginator paginator = new Paginator();
        paginator.setPage(NumberUtils.tryParseInt(request.getParameter("page"), 1));
        paginator.setPageSize(NumberUtils.tryParseInt(request.getParameter("page_size"), 50));
        paginator.getOrders().add(Pair.of("createTime", false));
        List<CommentEntity> commentEntities = productService.getComments(productId, paginator);
        if(request.getParameter("page")!=null) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("records", commentEntities);
            jsonObject.put("total", paginator.getTotal());
            return SimpleResponse.ok(jsonObject).toJSON();
        }
        return SimpleResponse.ok(commentEntities).toJSON();
    }
    
    @RequestMapping(value = "/add_comment", method = RequestMethod.POST)
    public @ResponseBody
    String addProductComment(HttpServletRequest request, CreateProductCommentForm createProductCommentForm) {
        BindingResult bindingResult = validator.validate(createProductCommentForm);
        if(bindingResult.hasErrors()) {
            return SimpleResponse.fail(bindingResult.getErrors().next().getErrorMessage()).toJSON();
        }
        String username = (String) request.getSession(true).getAttribute("username");
        if(StringUtil.isEmpty(username)) {
            return SimpleResponse.fail("当前没有登陆").toJSON();
        }
        UserEntity userEntity = userService.findByUsername(username);
        if(userEntity == null) {
            return SimpleResponse.fail("找不到用户" + username).toJSON();
        }
        try {
            CommentEntity commentEntity = productService.createProductComment(userEntity.getId(), createProductCommentForm.getProductId(), createProductCommentForm.getTitle(), createProductCommentForm.getContent());
            return SimpleResponse.ok(commentEntity).toJSON();
        } catch (ProductException e) {
            LOG.error("create product comment error", e);
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
    }
    
    @RequestMapping(value = "/collect/{productId}", method = RequestMethod.POST)
    public @ResponseBody
    String collectProduct(HttpServletRequest request, @PathVariable String productId) {
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        productService.collectProduct(productId, userEntity.getId());
        return SimpleResponse.ok("done").toJSON();
    }

    @RequestMapping(value = "/uncollect/{productId}", method = RequestMethod.POST)
    public @ResponseBody
    String unCollectProduct(HttpServletRequest request, @PathVariable String productId) {
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        productService.unCollectProduct(productId, userEntity.getId());
        return SimpleResponse.ok("done").toJSON();
    }

    @RequestMapping(value = "/has_collected/{productId}", method = RequestMethod.POST)
    public @ResponseBody
    String hasCollected(HttpServletRequest request, @PathVariable String productId) {
        UserEntity userEntity;
        try {
            userEntity = httpManager.currentUser(request);
        } catch (UserException e) {
            return SimpleResponse.fail(e.getMessage()).toJSON();
        }
        boolean hasCollected = productService.isCollectedProduct(productId, userEntity.getId());
        return SimpleResponse.ok(hasCollected).toJSON();
    }
    
    @RequestMapping("/user_collected/{userId}")
    public @ResponseBody
    String getUserCollectedProducts(HttpServletRequest request, @PathVariable String userId) {
        Paginator paginator = new Paginator();
        paginator.setPage(NumberUtils.tryParseInt(request.getParameter("page"), 1));
        paginator.setPageSize(NumberUtils.tryParseInt(request.getParameter("page_size"), 10));
        paginator.setPageSize(10);
        List<ProductEntity> productEntities = productService.getUserCollectedProducts(userId, paginator);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("records", productEntities);
        jsonObject.put("total", paginator.getTotal());
        return SimpleResponse.ok(jsonObject).toJSON();
    }
}
